﻿using System;
using System.Windows.Input;

namespace Foundation
{
    /// <summary>
    /// Command implementation.
    /// </summary>
    public class Command : ICommand
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Command"/> class.
        /// </summary>
        /// <param name="onExecute">The on execute.</param>
        /// <param name="onCanExecute">The on can execute.</param>
        public Command(Proc onExecute, Func<object,bool> onCanExecute = null)
        {
            OnExecute += o => { };
            OnCanExecute += o => true;

            if (onExecute != null)
            {
                OnExecute += onExecute;
            }

            if (onCanExecute != null)
            {
                OnCanExecute += onCanExecute;
            }
        }

        public delegate void Proc(object parameter);

        /// <summary>
        /// Occurs when changes occur that affect whether or not the command should execute.
        /// </summary>
        public event EventHandler CanExecuteChanged;

        public Proc OnExecute;

        public Func<object, bool> OnCanExecute;

        /// <summary>
        /// Defines the method to be called when the command is invoked.
        /// </summary>
        /// <param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
        public void Execute(object parameter)
        {
            OnExecute(parameter);
        }

        /// <summary>
        /// Defines the method that determines whether the command can execute in its current state.
        /// </summary>
        /// <param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
        /// <returns>
        /// true if this command can be executed; otherwise, false.
        /// </returns>
        public bool CanExecute(object parameter)
        {
            return OnCanExecute(parameter);
        }

        /// <summary>
        /// Notifies the when can execute changed.
        /// </summary>
        public void NotifyWhenCanExecuteChanged()
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
    }
}
